/*
============================================================================
 Name        : $(Basename)Session.cpp
 Author      : $(Author)
 Version     :
 Copyright   : $(Copyright)
 Description : $(Basename)Server session.
============================================================================
*/

#include "$(Basename)Server.h"
#include "$(Basename)Session.h"

C$(Basename)ServerSession* C$(Basename)ServerSession::NewL(RThread& aClient, C$(Basename)Server& aServer)
    {
    C$(Basename)ServerSession* self = C$(Basename)ServerSession::NewLC(aClient, aServer);
    CleanupStack::Pop(self);
    return self;
    }

C$(Basename)ServerSession* C$(Basename)ServerSession::NewLC(RThread& aClient, C$(Basename)Server& aServer)
    {
    C$(Basename)ServerSession* self = new(ELeave) C$(Basename)ServerSession(aClient, aServer);
    CleanupStack::PushL(self);
    self->ConstructL();
    return self;
    }

C$(Basename)ServerSession::C$(Basename)ServerSession(RThread& aClient, C$(Basename)Server& aServer)
: CSession(aClient), iServer(aServer)
    {
    }

void C$(Basename)ServerSession::ConstructL()
    {
    iServer.IncrementSessions();
    }

C$(Basename)ServerSession::~C$(Basename)ServerSession()
    {
    iServer.DecrementSessions();
    }

void C$(Basename)ServerSession::ServiceL(const RMessage& aMessage)
    {
    switch (aMessage.Function())
        {
        case E$(Basename)ServRequestTime:
            RequestTimeL(aMessage);
            break;
        case E$(Basename)ServCancelRequestTime:
            if(iWaitingForTick)
                {
                iMessage.Complete(KErrCancel);
                iWaitingForTick = EFalse;
                }
            aMessage.Complete(KErrNone);
            break;
        default:
            PanicClient(EBadRequest);
        }
    }

void C$(Basename)ServerSession::RequestTimeL(const RMessage& aMessage)
    {
    if(iWaitingForTick)
        {
        PanicClient(EReqAlreadyPending);
        }
    else
        {
        iMessage = aMessage;

        // Start the work performed by the server
        // (just a wait for new second in this example)
        iServer.WaitForTickL();
        iWaitingForTick = ETrue;
        }
    }

void C$(Basename)ServerSession::SendTimeToClient()
    {
    if(iWaitingForTick)
        {
        iWaitingForTick = EFalse;

        TTime time;
        time.HomeTime();

        // Create a descriptor which points to the 'time' structure
        TPtr8 ptr(reinterpret_cast<TUint8*>(&time), sizeof(time), sizeof(time));
        TRAPD(leave, iMessage.WriteL(iMessage.Ptr0(), ptr));
        if(leave)
            {
            PanicClient(EBadDescriptor);
            }

        iMessage.Complete(E$(Basename)ServRequestTimeComplete);
        }
    }

void C$(Basename)ServerSession::PanicClient(TInt aPanic) const
    {
    Panic(K$(Basename)Server, aPanic);
    }
